package com.future.bs.component.stream;

import com.future.bs.component.business.Business;
import com.future.bs.context.Context;
import com.future.bs.component.business.BusinessPredicate;
import com.future.bs.component.report.Report;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * 可重复执行业务流
 * </p>
 *
 * @author Jingjie
 * @since 2020-11-08 09:56
 */
public class RepeatableStream<T extends Context> extends Stream<T> {
    private static final Logger LOGGER = LoggerFactory.getLogger(RepeatableStream.class);

    private Business<T> business;
    private BusinessPredicate<T> businessPredicate;

    @Override
    public Report<T> execute(T context) {
        Report<T> report;
        do {
            // run this business at least once
            report = business.execute(context);
        } while (businessPredicate.apply(report)); // predicate
        LOGGER.info("End execute repeatable business stream '{}'.", getName());
        return report;
    }

    /**
     * <p>
     * 建造器
     * </p>
     *
     * @author Jingjie
     * @since 2020-11-08 09:55
     */
    public class Builder {
        private String name;
        private Business<T> business;
        private BusinessPredicate<T> businessPredicate;

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder process(Business<T> business) {
            this.business = business;
            return this;
        }

        public Builder predicate(BusinessPredicate<T> businessPredicate) {
            this.businessPredicate = businessPredicate;
            return this;
        }

        public RepeatableStream<T> build() {
            RepeatableStream.this.name = this.name;
            RepeatableStream.this.business = this.business;
            RepeatableStream.this.businessPredicate = this.businessPredicate;
            return RepeatableStream.this;
        }
    }
}
